using COC.Constant;
using COC.Debug;
using COC.UIAction;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class CharacterDisplayTemplate : MonoBehaviour
{
    public HealthComponent health;
    public CharacterState state;
    public AnimationTemplate animator;
    public Particle defaultParticle;
    public int raduis;
    public Shader shareShader;
    public Mesh defaultMesh;
    public GameObject dash;//using material that display object range,for example:red to which ban to drag this objct,greeen is indicated to move when player touched this object

    public Mesh dashMesh;
    int direction = 0; //0=left 1=right 2=up 3=down
    public Component collider;
    public Dictionary<Vector3, int> mAllTileNodes = null;
    public float mTileSize;
    public float mSpace = 1; //default space is one unit.
    public float xOffset = 0.3f;
    public float yOffset = 0.0f;
    public float zOffset = 0.3f;
    public float xMapCount = 0;
    public float yMapCount = 0;
    public int segmentWidthTileCount = 0;
    public int segmentHeightTileCount = 0;
    public bool isEdit = false;
    public Vector3 mouseCursorPosition = Vector3.zero;
    public Vector3 centerAxis = Vector3.zero;
    private TileMapDemo ancestorMonitor = null;
    private Rigidbody mRigidBody;
    CQuad<Vector3, Vector3, int, int>
            mMapPivotSpace = new CQuad<Vector3, Vector3, int, int>(); //deault unit space by target character 
    CQuad<Vector3, Vector3, int, int>
            mPivotSpace = new CQuad<Vector3, Vector3, int, int>(); //deault unit space by target character 
    //Vector3[] direction = new Vector3[4];
    CQuad<Vector3, Vector3, int, int> movePivotSpace = new CQuad<Vector3, Vector3, int, int>();
    private bool canMove = false;
    private Camera mCamera;
    public float addHeightWhenClicked = 2.0f;
    Transform mTransform;
    public GameObject mCharacterModel;
    float yPos;
    float moveLimit = .5f;
    float sqrMoveLimit;

    void Awake()
    {
        centerAxis = this.transform.localPosition;
        dash = GameObject.CreatePrimitive(PrimitiveType.Cube);
        dash.name = this.name + "_" + "dash";
        //dash.transform.parent = this.transform;
        dash.transform.parent = this.transform;
        dash.transform.position = this.transform.position;
        dash.transform.localScale = new Vector3(transform.localScale.x, transform.localScale.y, transform.localScale.z);
        //MeshFilter mf=dash.AddComponent<MeshFilter> ();
        //dashMesh = this.gameObject.GetComponent<MeshFilter> ().mesh;
        //mf.mesh = dashMesh;
        //dash.AddComponent<MeshRenderer> ();
        dash.renderer.material.color = Color.gray;
        //CaculatingVerticesByRange (transform,mTileSize);


    }

    void Start()
    {
        mouseCursorPosition = centerAxis;
        isEdit = true;
        //mRigidBody = this.rigidbody;
        mCamera = Camera.main;
        mTransform = this.transform;
        sqrMoveLimit = moveLimit * moveLimit;   // Since we're using sqrMagnitude, which is faster than magnitude
        //mRigidBody.isKinematic = true;
        //				Debug.Log ("Initializing character is successful.");
    }
    /*
            void OnMouseDown ()
            {
                    //canMove = true;
                    //mRigidBody.isKinematic = false;
                    mTransform.Translate (Vector3.up * addHeightWhenClicked);	
                    yPos = mTransform.position.y;
					
		
            }
	
            void OnMouseUp ()
            {

                    //canMove = false;
                    //mRigidBody.isKinematic = true;
                    Vector3 pos = mTransform.position;
                    pos.y = yPos - addHeightWhenClicked;
				
                    mTransform.position = pos;
		       
            }*/

    void OnTriggerEnter(Collider col)
    {
        if (TileMapDemo.isPlaceAll)
            if (col.transform.tag.Equals(CommonConstants.BUILD_MODEL_TAG))
            {
                transform.renderer.material.color = Color.blue;

                if (col.name != transform.name)
                    CampAction.setColliderInfo(col.transform.name);
                // DebugTool.Log("COLLIDER NAME:"+col.transform.name);
                else
                {
                    CampAction.setColliderInfo("");
                }

            }
    }
    private void Update()
    {
    }

    void FixedUpdate()
    {

        if (isEdit)
        {
            //if (!canMove) {
            //        return;
            //}
            //mRigidBody.angularVelocity = Vector3.zero;
            //Vector3 pos = mTransform.position;
            //pos.y = yPos;
            //mTransform.position = pos;
            //if (Input.GetMouseButton (0)) {
            //        mouseCursorPosition = Input.mousePosition;
            //        Vector3 move = mCamera.ScreenToWorldPoint (new Vector3 (mouseCursorPosition.x, mouseCursorPosition.y, mCamera.transform.position.y - mTransform.position.y)) - mTransform.position;
            //        move.y = 0.0f;
            //        if (Mathf.Abs (move.x) > xOffset || Mathf.Abs (move.z) > yOffset) {

            //                move.x += mTileSize + xOffset;
            //                if (move.sqrMagnitude > sqrMoveLimit) {
            //                        move = move.normalized * moveLimit;
            //                }
            //                mRigidBody.MovePosition (mRigidBody.position + move);
            //                //centerAxis += Vector3.right * (mTileSize + xOffset) + Vector3.up * (mTileSize + yOffset);
            //                //this.transform.localPosition = Vector3.MoveTowards (this.transform.localPosition, centerAxis, Time.deltaTime * 23.05f);
            //                //ancestorMonitor.adjustAnchorPosition2 (centerAxis, segmentWidthTileCount, segmentHeightTileCount, false);
            //                //Debug.Log ("centerAxis =[" + centerAxis.x + "," + centerAxis.y + "," + centerAxis.z + "].");

            //                //if (Vector3.Distance (centerAxis, mouseCursor) > 1) {
            //                //		return;     
            //                //}
            //        }
            //}
        }
    }

    void CaculatingVerticesByRange(Transform target, float tileSize)
    {
        Vector3 v3 = Vector3.zero;
        Vector3 scale = target.localScale;
        int mLocalX = (int)target.localScale.x;
        int mLocalZ = (int)target.localScale.z;
        int counts = mLocalX * mLocalZ;

        Vector3[] vertices = new Vector3[counts];
        int index = 0;
        for (int x = 0; x < mLocalX; x++)
        {
            for (int y = 0; y < mLocalZ; y++)
            {
                v3 += new Vector3(x * tileSize + xOffset, 0.0f, y * tileSize + zOffset);
                vertices[index] = v3;
                UnityEngine.Debug.Log("vector[x=" + v3.x + ",y=" + v3.y + ",z=" + v3.z + "];");
                index++;
            }
        }

        index = 0;
        int segmentWidth = mLocalX / 2;
        int segmentHeight = mLocalZ / 2;
        //int l = ((counts / 4)) % 2 == 0 ? ((counts / 4)) : ((counts / 4)) - 1;
        int[] triangles = new int[(segmentWidth * segmentHeight) * 6];
        if (UnityEngine.Debug.isDebugBuild)
        {
            UnityEngine.Debug.Log("counts =" + counts + "triangles =" + triangles.Length + ";mLocalX =" + mLocalX + "; mLocalZ" + mLocalZ);
        }
        for (int x = 0; x < segmentWidth; x++)
        {
            if (x % 2 == 0)
            {
                for (int y = 0; y < segmentHeight; y++)
                {
                    triangles[index] = y * 2;
                    triangles[index + 1] = y * 2 + 1;
                    triangles[index + 2] = 2 * (y + 3) + x + 1;

                    triangles[index + 3] = 2 * y;
                    triangles[index + 4] = 2 * (y + 3);
                    triangles[index + 5] = 2 * (y + 3) + x + 1;
                    index += 6;
                }
            }
            else
            {
                for (int y = 0; y < segmentHeight; y++)
                {
                    triangles[index] = (y + 6) * 2;
                    triangles[index + 1] = (y + 6) * 2 + 1;
                    triangles[index + 2] = 2 * (y + 9) + 1;

                    triangles[index + 3] = (y * 6) * 2;
                    triangles[index + 4] = 2 * (y + 9);
                    triangles[index + 5] = 2 * (y + 9) + 1;
                    index += 6;
                }
            }

        }
        Debug.Log("index =" + index);
        MeshFilter mf = dash.GetComponent<MeshFilter>();
        dashMesh = new Mesh();
        dashMesh.vertices = vertices;
        Debug.Log("dashMesh.triangles=" + dashMesh.triangles.Length);
        dashMesh.triangles = triangles;
        mf.sharedMesh = dashMesh;
        dashMesh.RecalculateBounds();
        MeshRenderer mr = dash.GetComponent<MeshRenderer>();
        mr.material.color = Color.green;
        return;
    }

    GameObject searchPivotXY(GameObject markNode, GameObject parent, Vector3 currVet3)
    {
        //buildModel = null;
        markNode = null;
        mPivotSpace.item1 = new Vector3(mPivotSpace.item1.x, 0.0f, 0.0f);
        mPivotSpace.item2 = new Vector3(mPivotSpace.item1.x + segmentWidthTileCount * (mTileSize + xOffset), 0.0f, mPivotSpace.item1.z + segmentHeightTileCount * (mTileSize + xOffset));
        mPivotSpace.item3 = (int)segmentWidthTileCount;
        mPivotSpace.item4 = (int)segmentHeightTileCount;
        Debug.Log("----------------ORIGIN----------------mPivotSpace.item1 = [" + mPivotSpace.item1.x + "," +
                "" + mPivotSpace.item1.y + "," + mPivotSpace.item1.z + "];" +
                "mPivotSpace.item2 =[" + mPivotSpace.item2.x + "," + mPivotSpace.item2.y + "," + mPivotSpace.item2.z);
        //Debug.Log ("mPivotSpace.value1.x =" + mPivotSpace.item1.x);
        if (mPivotSpace.item1.x < mAllTileNodes.Count - 1)
        {
            if (isDefaultOccupySpceByCharacter(movePivotSpace, mAllTileNodes, (int)xMapCount, (int)yMapCount))
            {
                Debug.Log("Instiate and now");
                markNode = Object.Instantiate(Resources.Load("FBX/ShouLan")) as GameObject;
                markNode.name = "markNode_" + (int)currVet3.x + "_" + (int)currVet3.z;
                markNode.transform.parent = parent.transform;
                //markNode.transform.localPosition = new Vector3 (currVet3.x + 1, currVet3.y + 1.0f, currVet3.z + 1);
                Debug.Log("(movePivotSpace.item2.z)/2+segmentHeightTileCount*yOffset =" + (movePivotSpace.item2.z) / 2);
                markNode.transform.localPosition = new Vector3(movePivotSpace.item1.x + ((segmentWidthTileCount - 1) * (mTileSize + yOffset)) / 2, movePivotSpace.item1.y + 3.0f, movePivotSpace.item1.z + ((segmentHeightTileCount - 1) * (mTileSize + yOffset)) / 2);
                //markNode.transform.localScale = new Vector3 ((segmentWidthTileCount-1)*(tileSize+xOffset)+tileSize, 0.2f, (segmentHeightTileCount-1)*(tileSize+yOffset)+tileSize);

                //Debug.Log ("mPivotSpace.item.x =" + mPivotSpace.item1.x + ",mPivotSpace.item1.z =" + mPivotSpace.item1.z + ";");

                //range
                GameObject t2 = GameObject.CreatePrimitive(PrimitiveType.Cube);

                t2.name = "rang" + (int)currVet3.x + "_" + (int)currVet3.z;
                //TileNode node = t.AddComponent<TileNode> ();
                //node.parent=defaultMap;
                t2.transform.parent = parent.transform;
                t2.transform.localPosition = new Vector3(movePivotSpace.item1.x + ((segmentWidthTileCount - 1) * (mTileSize + yOffset)) / 2, movePivotSpace.item1.y + 0.88f, (movePivotSpace.item1.z + ((segmentHeightTileCount - 1) * (mTileSize + yOffset)) / 2));
                //t.transform.localPosition = new Vector3 (movePivotSpace.item1.x, movePivotSpace.item1.y + 3.0f, movePivotSpace.item1.z);
                t2.transform.localScale = new Vector3((segmentWidthTileCount - 1) * (mTileSize + xOffset) + mTileSize, 0.2f, (segmentHeightTileCount - 1) * (mTileSize + yOffset) + mTileSize);
                t2.renderer.material.color = Color.green;
                //buildModel = new GameObject ();
                //buildModel.name = "Build_Model" + currVet3.x + "_" + (int)currVet3.z;
                //buildModel.transform.parent = parent.transform;
                //buildModel.transform.localPosition = new Vector3 (movePivotSpace.item1.x+((segmentWidthTileCount-1) * (tileSize+yOffset))/2, movePivotSpace.item1.y + 3.0f, movePivotSpace.item1.z+((segmentHeightTileCount-1) * (tileSize+yOffset))/2);
                //markNode.transform.parent = buildModel.transform;
                //t2.transform.parent = buildModel.transform;
                return null;
            }
            searchPivotXY(markNode, parent, currVet3);
        }
        return null;
    }

    bool isDefaultOccupySpceByCharacter(CQuad<Vector3, Vector3, int, int> pivotSpace, Dictionary<Vector3, int> allTileNodes, int xCount, int yCount)
    {
        //reset unit space
        //occupy space by current character 
        Vector3 pivotHorizontal = pivotSpace.item1;
        Vector3 pivotVertical = pivotSpace.item2;
        int xSegmentWidth = pivotSpace.item3;
        int ySegmentHeight = pivotSpace.item4;
        int currAvailabe = 1;
        int countX = xSegmentWidth;
        int countY = ySegmentHeight;
        //Debug.Log ("xSegmentWidth =" + xSegmentWidth);
        int step = 1;
        bool isDefault = false;
        Vector3 vX = Vector3.zero;
        Vector3 vY = Vector3.zero;
        movePivotSpace.item3 = xSegmentWidth;
        movePivotSpace.item4 = ySegmentHeight;
        {
            //whether vector3 is unavailable
            //allTileNodes.TryGetValue (pivot, out currAvailabe);







            direction = 1;
            switch (direction)
            {
                //move target 
                //left direction

                case 0:
                    vX.x = -step * (mTileSize + xOffset);
                    vY.x = -step * (mTileSize + xOffset);

                    vY.z = step * (countY * (mTileSize + yOffset));
                    pivotHorizontal += vX;
                    pivotVertical += vY;
                    movePivotSpace.item1 = pivotHorizontal;
                    movePivotSpace.item2 = pivotVertical;
                    currAvailabe = estimateAvailableSpace(movePivotSpace, currAvailabe, allTileNodes);

                    break;
                case 1:
                    //right direction
                    vX.x = step * (mTileSize + xOffset);
                    vY.x = step * (mTileSize + xOffset);
                    pivotHorizontal += vX;
                    pivotVertical += vY;
                    movePivotSpace.item1 = pivotHorizontal;
                    movePivotSpace.item2 = pivotVertical;
                    Debug.Log("----------------MOVING----------------movePivotSpace.item1 = [" + mPivotSpace.item1.x + "," +
                            "" + movePivotSpace.item1.y + "," + movePivotSpace.item1.z + "];" +
                            "movePivotSpace.item2 =[" + movePivotSpace.item2.x + "," + movePivotSpace.item2.y + "," + movePivotSpace.item2.z + "]");
                    currAvailabe = estimateAvailableSpace(movePivotSpace, currAvailabe, allTileNodes);
                    break;
                case 2:
                    //forward direction
                    vX.z = step * (mTileSize + yOffset);
                    vY.x = step * (countX * (mTileSize + xOffset));
                    vX.z = step * (mTileSize + yOffset);
                    pivotHorizontal += vX;
                    pivotVertical += vY;
                    movePivotSpace.item1 = pivotHorizontal;
                    movePivotSpace.item2 = pivotVertical;
                    currAvailabe = estimateAvailableSpace(pivotSpace, currAvailabe, allTileNodes);

                    break;
                //downward directon
                case 3:
                    vX.z = -step * (mTileSize + yOffset);
                    vY.x = step * (countX * (mTileSize + xOffset));
                    vX.z = -step * (mTileSize + yOffset);
                    pivotHorizontal += vX;
                    pivotVertical += vY;
                    movePivotSpace.item1 = pivotHorizontal;
                    movePivotSpace.item2 = pivotVertical;
                    currAvailabe = estimateAvailableSpace(pivotSpace, currAvailabe, allTileNodes);

                    break;
                default:
                    currAvailabe += 1;
                    break;
            }
        }
        Debug.Log("currAvailabe ===========" + currAvailabe);
        if (currAvailabe == 1)
        {

            isDefault = true;
        }
        return isDefault;
    }

    int estimateAvailableSpace(CQuad<Vector3, Vector3, int, int> pivotSpace, int currAvailabe, Dictionary<Vector3, int> allTileNodes)
    {
        int _ca = 1;
        Vector3 pivotHorizontal = pivotSpace.item1;
        Vector3 pivotVertical = pivotSpace.item2;
        int xSegmentWidth = pivotSpace.item3;
        int ySegmentHeight = pivotSpace.item4;
        Vector3 segmentSpace = Vector3.zero;

        Vector3 currX = pivotHorizontal;
        Vector3 currY = pivotVertical;
        Debug.Log("pivotHorizontal =[" + pivotHorizontal.x + "," + pivotHorizontal.y + "," + pivotHorizontal.z + "];" +
                "pivotVertical =[" + pivotVertical.x + "," +
                "" + pivotVertical.y + "," +
                "" + pivotVertical.z + "].");
        //Debug.Log ("xCount / 2=" + xCount / 2 + ";xSegmentWidth =" + xSegmentWidth + "; ySegmentHeight =" + ySegmentHeight + "; yCount / 2 =" + yCount / 2);
        if (currAvailabe != 0)
        {
            if ((xSegmentWidth > 1 && xSegmentWidth < xMapCount / 2) && (ySegmentHeight > 1 && ySegmentHeight < yMapCount / 2))
            {
                //if (xSegmentWidth < xCount / 2 || ySegmentHeight < yCount / 2) {

                //for (int i=0; i<xSegmentWidth; i++) {
                //	for (int j=0; j<ySegmentHeight; j++) {
                //		allTileNodes.Remove (curr);


                //	}
                //}
                Debug.Log("-----------------I'm coming 1-----------");
                if (allTileNodes.ContainsKey(currX) && allTileNodes.ContainsKey(currY))
                {
                    allTileNodes.TryGetValue(currX, out currAvailabe);
                    _ca += currAvailabe;
                    allTileNodes.TryGetValue(currY, out currAvailabe);
                    _ca += currAvailabe;
                    string a = (_ca == 1) ? "Available" : "UnAvailable";
                    Debug.Log("currX and currY is " + a + "------------1------------");
                    return _ca;
                }

            }
            if ((xSegmentWidth > 1 && xSegmentWidth < xMapCount / 2) || (ySegmentHeight > 1 && ySegmentHeight < yMapCount / 2))
            {
                //if (xSegmentWidth < xCount / 2 || ySegmentHeight < yCount / 2) {
                Debug.Log("----------------I'm coming 2------------------");
                if (allTileNodes.ContainsKey(currX) && allTileNodes.ContainsKey(currY))
                {

                    allTileNodes.TryGetValue(currX, out currAvailabe);
                    _ca += currAvailabe;
                    allTileNodes.TryGetValue(currY, out currAvailabe);
                    _ca += currAvailabe;
                    string a = (_ca == 1) ? "Available" : "UnAvailable";
                    Debug.Log("currX and currY is " + a + "------------2------------");
                    return _ca;
                }
            }
        }

        return currAvailabe += 1;
    }
}

